package de.sehversuche.pse.access.pse5impl;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcDaoSupport;

import de.sehversuche.pse.access.PseCollectionDao;
import de.sehversuche.pse.model.PseCollection;
import de.sehversuche.pse.model.PseFolder;

/**
 * 
 * 
 * @author Lars
 * @see PseCollectionDao
 */
public class Pse5FolderDao extends SimpleJdbcDaoSupport implements PseCollectionDao,
		Pse5TableConstants {
	private Pse5FolderMapper rowMapper = new Pse5FolderMapper();
	private static final String FOLDER_SELECT = "SELECT fFolderId, fFolderName, "
			+ "fFirstChildFolderId, fNextFolderId, fFolderAttributes FROM FolderTable";

	/**
	 * @see PseCollectionDao#loadAllCollections()
	 */
	public List<PseFolder<PseCollection>> loadAllCollections() {
		// load root (pseudo) collection)
		Pse5Folder root = getSimpleJdbcTemplate().queryForObject(
				FOLDER_SELECT + " WHERE fFolderAttributes = ?", rowMapper,
				FOLDER_ATTRIBUTE_COLLECTION_ROOT);
		// check if any collections are present
		if (root.getFirstChildFolderId() != 0) {
			// load all collection groups and collections
			List<Pse5Folder> allLoaded = getSimpleJdbcTemplate().query(
					FOLDER_SELECT + " WHERE fFolderAttributes IN (?, ?, ?)", rowMapper,
					FOLDER_ATTRIBUTE_COLLECTION_GROUP, FOLDER_ATTRIBUTE_COLLECTION,
					FOLDER_ATTRIBUTE_MEDIA_LIBRARY);
			// put all entries in a map with key=id and value=collection
			Map<Long, Pse5Folder> all = new HashMap<Long, Pse5Folder>();
			for (Pse5Folder folder : allLoaded) {
				all.put(folder.getId(), folder);
			}

			PseCollection rootColl = root.toPseCollection(null);
			createPseCollectionWithChildren(all.get(root.getFirstChildFolderId()), rootColl, all);
			return rootColl.getChildren();
		} else {
			// no collections present, answer an empty list
			return Collections.emptyList();
		}
	}

	private void createPseCollectionWithChildren(Pse5Folder current, PseCollection parent,
			Map<Long, Pse5Folder> allFolders) {
		if (current.isPseCollection()) {
			// create PseCollection from current Pse5Folder
			PseCollection currentColl = current.toPseCollection(parent);
			parent.getChildren().add(currentColl);
			// add first child to current
			if (current.getFirstChildFolderId() != 0) {
				Pse5Folder firstChild = allFolders.get(current.getFirstChildFolderId());
				createPseCollectionWithChildren(firstChild, currentColl, allFolders);
			}
		}
		// add next folder to same parent
		if (current.getNextFolderId() != 0) {
			Pse5Folder next = allFolders.get(current.getNextFolderId());
			createPseCollectionWithChildren(next, parent, allFolders);
		}
	}

	/**
	 * Mapper creating {@link Pse5Folder}s.
	 */
	private class Pse5FolderMapper implements ParameterizedRowMapper<Pse5Folder> {
		public Pse5Folder mapRow(ResultSet rs, int row) throws SQLException {
			Pse5Folder folder = new Pse5Folder();
			folder.setId(rs.getLong(1));
			folder.setName(rs.getString(2));
			folder.setFirstChildFolderId(rs.getLong(3));
			folder.setNextFolderId(rs.getLong(4));
			folder.setFolderAttributes(rs.getLong(5));
			return folder;
		}
	}

}
